#ifndef IEC101DEVICE_H
#define IEC101DEVICE_H

/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author zhouyan
 * @brief iec101规约设备管理
*/
#include "iot_debug.h"
#include "dx_type.h"
#include "sys_inc.h"
#include "tools/m_mutex.h"
#include "iec101Impl.h"
#include "idevice.h"
#include "reginfo.h"

class IEC101Device : public IDevice, protected IEC101Impl
{
public:
    struct InfoObjReg {
        uint16_t addr;
        uint16_t num;
    };

    struct RegGroup {
        InfoObjReg obj;
        RegInfos infos;
    };
    typedef std::list<RegGroup> RegGroups;

    IEC101Device(uint16_t bay_id, uint16_t dev_id, IPhyLink *phy_dev);
    ~IEC101Device();

    int genDevice(cJSON *root, cJSON *model_root, const char *model_name,
                   uint64_t dev_addr, cJSON *arr_params);

    virtual bool isActived(void) const;

    virtual const RegBase * getYX(const char *reg_name);
    virtual bool hasYX(const char *reg_name);

    virtual const RegBase * getYC(const char *reg_name);
    virtual bool hasYC(const char *reg_name);

    virtual int updateReg(void);
    virtual int actions();
    virtual const char * phyLinkDeviceName(void) const;

    // debug msg
    virtual void dumpYX(void);
    virtual void dumpYC(void);
    virtual void clearRegs();

    virtual void getAllRegs(Datas &regs) const;
    virtual void getYX(Datas &datas, bool force);
    virtual void getYC(Datas &datas, bool force);

protected:
    virtual void OnLinkLost(void);
    virtual void OnSetSIP(uint16_t addr, SinglePointStatus sp);
    virtual void OnSetDIP(uint16_t addr, DoublePointStatus dp);
    virtual void OnSetMeasure(uint16_t addr, float v);

private:
    bool parseInfoObjReg(cJSON *root, InfoObjReg &obj);
    int parseRegGroup(cJSON *root, RegGroup & group, bool is_yc);
    int parseRegGroups(cJSON *root, const char *block_name, RegGroups & groups);
    void dumpData(const RegGroups &regs);
    RegBase * findReg(RegGroups &regs, const std::string &name);

private:
    uint16_t dev_addr_;
    std::string model_name_;

    RegGroups sip_regs_;
    RegGroups dip_regs_;
    RegGroups measure_regs_;

    MMutex yx_mtx_;
    MMutex dip_mtx_;
    MMutex measure_mtx_;
};

#endif // IEC101DEVICE_H
